package com.syl.starter.itools.common.utils;

import com.syl.starter.itools.base.utils.CloseUtils;
import com.syl.starter.itools.base.utils.LogUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Collection;
import java.util.List;

/**
 *  List 工具类
 * @author syl
 * @create 2018-06-18 18:30
 **/
public class ListUtils {
    private static Logger LOG = LoggerFactory.getLogger(ListUtils.class);

    /**
     * 判断集合是否为空 没有数据也视为空
     * @param collection collection
     * @return 是否空
     */
    public static <T> boolean isEmpty(Collection<T> collection){
        return collection == null || collection.size() <= 0;
    }

    /**
     * 判断集合是否不为为空 没有数据也视为空
     * @param collection 集合
     * @return
     */
    public static <T> boolean isNotEmpty(Collection<T> collection){
        return !isEmpty(collection);
    }

    /**
     * 数组是否为空  没有数据也视为空
     * @param objects 数组对象
     * @return 是否空
     */
    public static <T> boolean isEmpty(T[] objects){
        return objects == null || objects.length <= 0;
    }

    /**
     * 数组是否不为空  没有数据也视为空
     * @param objects 数组对象
     * @return 是否不为空
     */
    public static <T> boolean isNotEmpty(T[] objects){
        return !isEmpty(objects);
    }

    /**
     * 数组是否全部为空
     * ListUtils.isAllEmpty(null)                       = true
     * ListUtils.isAllEmpty([])                         = true
     * ListUtils.isAllEmpty([null, null])               = true
     * ListUtils.isAllEmpty([null, ""])                 = false
     * ListUtils.isAllEmpty(["abc", ""])                = false
     *
     * @param objects 数组对象
     * @return 是否全部值都为null
     */
    public static <T> boolean isAllEmpty(T[] objects) {
        if (isEmpty(objects)) return true;
        int count = 0;
        for (T object : objects) {
            if (object == null) count ++;
        }
        return count == objects.length;
    }

    /**
     * 数组是否全部为空
     * ListUtils.isAllEmpty(null)                       = true
     * ListUtils.isAllEmpty([])                         = true
     * ListUtils.isAllEmpty([null, null])               = true
     * ListUtils.isAllEmpty([null, ""])                 = false
     * ListUtils.isAllEmpty(["abc", ""])                = false
     *
     * @param objects 数组对象
     * @return 是否全部值都为null
     */
    public static <T> boolean isAllEmpty(Collection<T> objects) {
        if (isEmpty(objects)) return true;
        int count = 0;
        for (T object : objects) {
            if (object == null) count ++;
        }
        return count == objects.size();
    }

    /**
     * 强力判断数组是否全部为空
     * ListUtils.isAllEmptyStrong(null)                       = true
     * ListUtils.isAllEmptyStrong([])                         = true
     * ListUtils.isAllEmptyStrong([null, null])               = true
     * ListUtils.isAllEmptyStrong([null, ""])                 = true
     * ListUtils.isAllEmptyStrong(["abc", ""])                = false
     *
     * @param strings 数组对象
     * @return 是否全部值都为null
     */
    public static <T> boolean isAllEmptyStrong(String[] strings) {
        if (isEmpty(strings)) return true;
        int count = 0;
        for (String string : strings) {
            if (StringUtils.isEmpty(string)) count ++;
        }
        return count == strings.length;
    }

    /**
     * 强力判断数组是否全部为空
     * ListUtils.isAllEmptyStrong(null)                       = true
     * ListUtils.isAllEmptyStrong([])                         = true
     * ListUtils.isAllEmptyStrong([null, null])               = true
     * ListUtils.isAllEmptyStrong([null, ""])                 = true
     * ListUtils.isAllEmptyStrong(["abc", ""])                = false
     *
     * @param strings 数组对象
     * @return 是否全部值都为null
     */
    public static boolean isAllEmptyStrong(Collection<String> strings) {
        if (isEmpty(strings)) return true;
        int count = 0;
        for (String string : strings) {
            if (StringUtils.isEmpty(string)) count ++;
        }
        return count == strings.size();
    }

    /**
     * 集合中是否存在指定元素
     * ListUtils.contains(["a","b"], null)                 = false
     * ListUtils.contains(["a","b"], null, "a")            = false
     * ListUtils.contains(["a","b"], "c", "a")             = false
     * ListUtils.contains(["a","b", "c"], "c", "a")        = true
     * @param collection 集合
     * @param objects 集合中的元素
     * @return 是否包含
     */
    public static <T> boolean contains(Collection<T> collection, T[] objects){
        for (Object o : objects) {
            if(o == null)
                return false;
            if(!collection.contains(o))
                return false;
        }
        return true;
    }

    /**
     * 集合中是否含有任何一个元素
     * ListUtils.containsAny(["a","b"], null)                = false
     * ListUtils.containsAny(["a","b"], null, a)             = true
     * ListUtils.containsAny(["a","b"], c, a)                = true
     * @param collection 集合
     * @param objects 集合中的元素
     * @return 是否包含
     */
    public static <T> boolean containsAny(Collection<T> collection, T[] objects){
        boolean b = false;
        for (Object o : objects) {
            if(o == null)
                continue;
            if(collection.contains(o)) {
                b = true;
                break;
            }
        }
        return b;
    }

    /**
     * list 深度拷贝
     * @param src 如果是对象该对象需要序列化
     * @return 深度拷贝后的对象集合
     */
    public static <T> Collection<T> deepCopy(Collection<T> src) {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = null;
        ObjectInputStream in = null;
        Collection<T> dest = null;
        try {
            out = new ObjectOutputStream(byteOut);
            out.writeObject(src);
            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            in = new ObjectInputStream(byteIn);
            dest = (Collection<T>) in.readObject();
        } catch (IOException e) {
            LogUtils.error(LOG,"深度拷贝失败 目标对象可能没有序列化",e);
        } catch (ClassNotFoundException e) {
            LogUtils.error(LOG,"类不存在",e);
        }finally {
            CloseUtils.closeAll(in, out);
        }
        return dest;
    }

    /**
     * 分页list
     * @param list 要拆分的列表
     * @param pageSize 每页几条
     * @param <T>
     * @return
     */
    public static <T> List<T>[] splitList(List<T> list, int pageSize) {
        int total = list.size();
        //总页数
        int pageCount = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
        List<T>[] result = new List[pageCount];
        for(int i = 0; i < pageCount; i++) {
            int start = i * pageSize;
            //最后一条可能超出总数
            int end = Math.min((start + pageSize), total);
            List<T> subList = list.subList(start, end);
            result[i] = subList;
        }
        return result;
    }

}
